package com.ht.controller;

import com.alibaba.fastjson.JSON;
import com.ht.bean.*;
import com.ht.common.CaptchaUtil;
import com.ht.common.FileUpload;
import com.ht.service.HolidayStudentService;
import com.ht.service.KaoheService;
import com.ht.service.XueShengDuanService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Controller
@RequestMapping("/holidaystudent")
public class HolidayStudentController {
    @Resource
    private KaoheService ks;

    @Resource
    private HolidayStudentService holidayStudentService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;//运行时服务接口

    @Autowired
    private TaskService taskService;//任务服务接口

    @Autowired
    private HistoryService historyService;//历史任务服务接口

    @RequestMapping("/goholidaystudent")
    public String goholidaystudent() {
        return "holidaystudentlist";
    }

    /*
     *查看登录学生的请假条
     * @param
     * @return
     **/
    @RequestMapping("/stugoholiday")
    public String fillin() {
        return "stuholiday";
    }

    @RequestMapping("/goFillin")
    public String goFillin() {
        return "fillin";
    }

    //上传流程文件
    @RequestMapping("/stugoupload")
    public String goupload() {
        return "stuupload";
    }

    //去填写请假单
    @RequestMapping("/stugoapply")
    public String goapply(Model model) {
        List<Student> studentList = holidayStudentService.studentList();
        model.addAttribute("studentList", studentList);
        return "stuapply";
    }

    //去填写请假单
    @RequestMapping("/stugomyTask")
    public String gomyTask(Model model) {
        return "stumyTask";
    }

    /*
     *学生端查看我的请假条
     * @param
     * @return map
     **/
    @RequestMapping("/holidaystudentlist")
    @ResponseBody
    public Map stuHdList(Integer page, Integer limit, HolidayStudent holidayStudent, Student student, String stuId) {
        List<Map> list = holidayStudentService.selStuHol(stuId, (page - 1) * limit, limit, holidayStudent, student);
        Map map = new HashMap();
        map.put("code", 0);
        map.put("msg", "成功");
        map.put("count", holidayStudentService.countStuHol(stuId, holidayStudent, student));
        map.put("data", list);
        return map;
    }

    /*
     *后台查看所有学生请假信息
     * @param
     * @return
     **/
    @RequestMapping("/selectAllStuFillin")
    @ResponseBody
    public Map selectAllStuFillin(Integer page, Integer limit, HolidayStudent holidayStudent, Student student) {
        List<Map> list = holidayStudentService.selectAllStuFillin((page - 1) * limit, limit, holidayStudent, student);
        Map map = new HashMap();
        map.put("code", 0);
        map.put("msg", "成功");
        map.put("count", holidayStudentService.countAllStuFillin(holidayStudent, student));
        map.put("data", list);
        return map;
    }

    //上传流程文件
    @RequestMapping("/stuupload")
    public String upload(MultipartFile actfile) {
        try {
            Deployment deployment = repositoryService.createDeployment().name("部署学生请假流程图").addZipInputStream(new ZipInputStream(actfile.getInputStream())).deploy();
            //file.delete();//删除临时文件
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:stuallprod";//去所有流程定义列表
    }

    //查看所有流程定义ProcessDefinition
    @RequestMapping("/stuallprod")
    public String addprod(Model model) {
        //创建流程定义查询对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        processDefinitionQuery.latestVersion();
        //查询所有流程定义
        List<ProcessDefinition> stuqueryList = processDefinitionQuery.list();
        model.addAttribute("stuquertList", stuqueryList);
        return "stuallProcessDefinition";
    }

    //删除定义
    @RequestMapping("/studelprod")
    public String delprod(String id) {
        repositoryService.deleteDeployment(id, true);
        return "redirect:stuallprod";//去所有流程图定义列表
    }

    //查看流程图
    @RequestMapping("/stuviewImage")
    public void viewImage(String id, String imageName, HttpServletResponse resp) {
//读取流程图的流程图片
        InputStream in = repositoryService.getResourceAsStream(id, imageName);
        //把图片打印到网页
        try {
            OutputStream out = resp.getOutputStream();
            // 把图片的输入流程写入resp的输出流中
            byte[] b = new byte[1024];
            for (int len = -1; (len = in.read(b)) != -1; ) {
                out.write(b, 0, len);
            }
            // 关闭流
            out.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    //下载流程图的zip文件
    @RequestMapping("/stutoExport")
    public void toExport(String id, HttpServletResponse resp) {

        try {
            //设置response对象的头参数，attachment就是附件，filename=文件名称
            resp.setHeader("Content-disposition", "attachment;filename=" + id + ".zip");
            //下载的文件类型是zip文件
            resp.setContentType("application/x-zip-compressed");

            //----------------------------------------------------------------------------


            //通过id拿到流程定义
            ProcessDefinition processDefinition = repositoryService
                    .createProcessDefinitionQuery()
                    .processDefinitionId(id).singleResult();
            //部署id
            String deploymentId = processDefinition.getDeploymentId();

            //bpmn资源文件名称
            String resourceName_bpmn = processDefinition.getResourceName();
            //bpmn资源文件输入流
            InputStream inputStream_bpmn = repositoryService.getResourceAsStream(deploymentId, resourceName_bpmn);
            //png文件名称
            String resourceName_png = processDefinition.getDiagramResourceName();
            //png资源文件输入流
            InputStream inputStream_png = repositoryService.getResourceAsStream(deploymentId, resourceName_png);

            //------创建输出流，绑定到response对象-------------------------------------------------------
            OutputStream out = resp.getOutputStream();
            //创建ZIP输出对象，绑定到输出流
            ZipOutputStream zipo = new ZipOutputStream(out);

            //流复制
            byte[] b = new byte[1024];
            int len = -1;

            //定义zip压缩包中的文件对象（zip实体）
            ZipEntry ze = new ZipEntry(resourceName_bpmn);
            //把创建的实体对象放到压缩包中
            zipo.putNextEntry(ze);
            //文件内容拷贝
            while ((len = inputStream_bpmn.read(b, 0, 1024)) != -1) {
                zipo.write(b, 0, b.length);
            }
            zipo.closeEntry();
            //---------------
            ZipEntry ze1 = new ZipEntry(resourceName_png);
            zipo.putNextEntry(ze1);
            while ((len = inputStream_png.read(b, 0, 1024)) != -1) {
                zipo.write(b, 0, b.length);
            }
            //关闭流
            inputStream_bpmn.close();
            inputStream_png.close();
            zipo.flush();
            zipo.close();
            out.flush();
            out.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/stuaddApply")
    public String addApply(HolidayStudent holidayStudent, @Param("stuId") String stuId) {
        holidayStudent.setStatus(1);
        //调用方法保存单据
        holidayStudentService.addstuApplay(holidayStudent);
        //设置流程变量
        //设置流程变量，就是将用户的自定义信息带到流程中去绑定
        Map<String, Object> variables = new HashMap<>();
        variables.put("stuId", holidayStudent.getStuId()); //用户名称
        variables.put("holidayDay", holidayStudent.getHolidayDay());//请假天数
        variables.put("holidayId", holidayStudent.getHolidayId());//单据ID
        //任课老师
        String assignee = holidayStudentService.selectByTeacher(stuId);
        System.out.println("assignee任课老师是：" + assignee + "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
        //班主任
        String assignee2 = holidayStudentService.selectByClaTea(stuId);
        System.out.println("assignee2班主任是：" + assignee2 + "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
        //校董办
        String assignee3 = holidayStudentService.seleceByPrn();


        variables.put("assignee", assignee);
        variables.put("assignee2", assignee2);
        variables.put("assignee3", assignee3);

        //根据流程key启动流程实例
        ProcessInstance pi = runtimeService.startProcessInstanceByKey(holidayStudent.getProcessInstanceId(), variables);

        // //获取启动流程中当前需要办理的任务 (就是张三的填写申请任务 需要执行完 才能进行到下一个任务节点)
        Task task = taskService.createTaskQuery().processInstanceId(pi.getProcessInstanceId()).orderByProcessInstanceId().desc().singleResult();
        //根据任务ID完成当前任务 (填写也是一个任务 需要完成)
        taskService.complete(task.getId(), variables);
        System.out.println("申请成功...");

        Map map = new HashMap();
        map.put("code", "0");
        map.put("msg", "成功");

        return "redirect:stumyjob";
    }

    @RequestMapping("/stumyjob")
    public String myjob(HttpSession session, Model model) {
        String empID = session.getAttribute("empID").toString();
        List<HolidayStudent> holidaystudentList = holidayStudentService.selHoliday(empID);
        model.addAttribute("holidaystudentList", holidaystudentList);
        return "stumyJobList";
    }

    @RequestMapping("/stulookTaskImg")
    public String lookTaskImg(Integer holidayId, Model model, String processInstanceId) {
        try {
            /**
             * 1.在我的任务中传递的参数是instId（实例id）
             * 2.在我的申请单中传递的参数是job.jobId(单据id)
             * */
            //获取流程id
            //String processInstanceId = null;
            if (processInstanceId == null) {
                //通过单据id查找实例对象
                HistoricVariableInstance hvi = historyService.createHistoricVariableInstanceQuery().variableValueEquals("holidayId", holidayId).singleResult();
                processInstanceId = hvi.getProcessInstanceId();//获取流程实例ID
            }
            //  获取历史流程实例
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(processInstanceId).singleResult();

            if (historicProcessInstance == null) {
                throw new Exception();
            } else {
                //获取流程定义信息
                ProcessDefinition pd = repositoryService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
                // 获取流程定义的实体（包含了流程中的任务节点信息，连线信息）
                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) pd;
                // 获取流程历史中已执行节点，并按照节点在流程中执行先后顺序排序
                List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
                        .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
                // 已经激活的节点ID集合
                //激活的节点（1.任务已经完成；2.任务已经开始，但还未结束）
                List mapList = new ArrayList();
                //获取已经激活的节点ID
                for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
                    //getActivityId方法获取已经激活的节点id
                    ActivityImpl activityImpl = processDefinition.findActivity(activityInstance.getActivityId());
                    //获取当前节点在图片中的坐标位置，左上角坐标及长宽
                    int x = activityImpl.getX();
                    int y = activityImpl.getY();
                    int height = activityImpl.getHeight();
                    int width = activityImpl.getWidth();
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("x", x + 195);
                    map.put("y", y + 76);
                    map.put("height", height);
                    map.put("width", width);
                    mapList.add(map);
                }

                model.addAttribute("mapList", mapList);
                model.addAttribute("pd", pd);//流程定义
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "image";
    }

    @RequestMapping("/stumyTask")
    public String myTask(HttpSession session, Model model) {
        String empID = session.getAttribute("empID").toString();
        //获取当需要前用户办理的任务列表
        List<Task> stutaskList = taskService.createTaskQuery().taskAssignee(empID).list();
        model.addAttribute("stutaskList", stutaskList);
        System.out.println("我的任务列表" + stutaskList);
        return "stumyTask";
    }


    @RequestMapping("/stutaskDetail")
    public String taskDetail(String taskId, String instId, Model model) {
        //流程实例
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(instId).singleResult();

        //任务详情
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        //获取历史审批批注信息
        List<Comment> commentList = taskService.getProcessInstanceComments(task.getProcessInstanceId());

        //获取流程定义id
        String processDefineId = task.getProcessDefinitionId();
        //查询流程定义实体对象
        ProcessDefinitionEntity pdentity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefineId);
        //获取当前活动id
        String activeId = pi.getActivityId();
        //获取当前活动
        ActivityImpl impl = pdentity.findActivity(activeId);


        //获取当前活动结束之后连线的名称
        List<Map> pvmList = new ArrayList<Map>();


        //根据当前节点 获取之后的连线列表
        List<PvmTransition> plist = impl.getOutgoingTransitions();
        for (PvmTransition pvm : plist) {
            Map map = new HashMap();
            if (pvm.getProperty("name") == null) {
                map.put("id", "2");
                map.put("name", "同意");
                map.put("name2", "不同意");
            } else {
                map.put("id", pvm.getId());
                map.put("name", pvm.getProperty("name") + "");
            }
            pvmList.add(map);
        }

        //反向根据任务ID 得到jobId
        int holidayId = Integer.parseInt(taskService.getVariable(taskId, "holidayId").toString());
        System.out.println("holidayId=" + taskService.getVariable(taskId, "holidayId") + "hhhhhhhhhhhhhh");

        //取出请假单数据
        HolidayStudent holidayStudent = holidayStudentService.findObjById(holidayId);


        model.addAttribute("stucommentList", commentList);
        model.addAttribute("stupvmList", pvmList);
        System.out.println("审批选项选项：" + pvmList);
        model.addAttribute("holidaystudent", holidayStudent);
        System.out.println("请假人：" + holidayStudent);
        model.addAttribute("taskId", taskId);
        System.out.println("taskId = " + taskId);
        return "stuadult";
    }

    @RequestMapping("/stucomplete")
    public String complete(String taskId, Integer holidayId, HttpSession session, String comment, String flow) {
        //获取当前Task对象
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        //获取当前实例对象Id
        String processId = task.getProcessInstanceId();
        //获取jobId变量
        //取出请假单数据
        HolidayStudent holidayStudent = holidayStudentService.findObjById(holidayId);
        //获取当前登录的用户id
        String empID = session.getAttribute("empID").toString();
        //添加备注的处理人
        Authentication.setAuthenticatedUserId(empID);
        //添加审批意见
        taskService.addComment(taskId, processId, comment);
        //添加任务变量
        Map<String, Object> var = new HashMap<String, Object>();
        var.put("flow", flow);
//    	var.put("assignee", userid);
        //完成当前任务
        taskService.complete(taskId, var);


        //判断当前流程是否已经审批结束
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
        //如果pi==null表示流程审批结束
        if (pi == null) {
            if (flow.equals("不同意")) {
                //更新job表的状态为2
                holidayStudent.setStatus(3);
            } else {
                holidayStudent.setStatus(2);
            }
            holidayStudentService.updHoliday(holidayStudent);
        }
        return "redirect:stumyTask";
    }

    @RequestMapping("/stulookComment")
    public String lookComment(Integer holidayId, Model model) {
        //通过单据id查找实例对象
        HistoricVariableInstance hvi = historyService.createHistoricVariableInstanceQuery().variableValueEquals("holidayId", holidayId).singleResult();
        //获取流程实例id
        String piId = hvi.getProcessInstanceId();
        //通过实例id查找批注信息列表
        List<Comment> commentList = taskService.getProcessInstanceComments(piId);
        model.addAttribute("stucommentList", commentList);
        return "comment";
    }


//    -----------------------------------------------------------------------------------------------------------------------------------------
//    申请维修，问题反馈，修改密码，个人主页

    @Resource
    private XueShengDuanService xsdS;

    //维修管理新增
    @RequestMapping("/toaddweixiu")
    public String weixiutoadd(Model model){

        //查询班级
        List<Studentclass> bjlist = xsdS.allstuclass();
        model.addAttribute("blist",bjlist);
        //查询部门
        List<Map> bmlist = xsdS.alldep();
        model.addAttribute("bmlist",bmlist);
        return "stuweixiu";
    }


    //维修管理新增
    @RequestMapping("/weixiuadd")
    @ResponseBody
    public Map weixiuadd(Student student, Integer equipmentId, Equipmentrepair equipmentrepair, HttpSession session){


        Map map=new HashMap();
        boolean bln=xsdS.addweixiu(equipmentrepair);
        System.out.println(bln);
        if(bln){
            map.put("mag","申请成功");
        }else{
            map.put("mag","申请失败");
        }
        return map;
    }

    //问题反馈
    @RequestMapping("/tofankuiadd")
    public String tofankuiadd(Model model){

        //查询班级
        List<Studentclass> bjlist = xsdS.allstuclass();
        model.addAttribute("blist",bjlist);
        //查询部门
        List<Map> bmlist = xsdS.alldep();
        model.addAttribute("bmlist",bmlist);
        //查询员工
        List<Map> yglist = xsdS.allemp();
        model.addAttribute("yglist",yglist);

        return "stufankui";
    }

    //添加问题反馈
    @RequestMapping("/fankuiadd")
    @ResponseBody
    public Map fankuiadd(Integer classId, Student student, Feedback feedback, @RequestParam("fileface") MultipartFile fileface, HttpSession session){

        System.out.println();


        String filePath = FileUpload.upload(fileface,session,"face");
        if(filePath!=null){
            feedback.setImage(filePath);
        }
        feedback.setFeedbackTime(new Date().toLocaleString());
        feedback.setReplyTime(new Date().toLocaleString());

//        Integer feedBackType = Integer.parseInt((String) session.getAttribute("feedBackType"));
        String stuname = (String)session.getAttribute("STUNAME");
        Student className = (Student)session.getAttribute("STU");
        System.out.println("-------******"+className.getClazz());

        String classname =  xsdS.stuclass(className.getClazz());


        feedback.setEmpName(classname+":"+stuname);
//        studentclass.setClassName(className);

        Map map=new HashMap();
        boolean bln=xsdS.addfankui(feedback);
        System.out.println(bln);
        if(bln){
            map.put("mag","反馈提交成功");
        }else{
            map.put("mag","反馈提交失败");
        }
        return map;
    }

    //去个人主页
    @RequestMapping("/topersonage")
    public String personage(){

        return "personage";
    }

    //去修改密码
    @RequestMapping("/topswup")
    public String topswup(){
        return "topswup";
    }

    //修改密码
    @RequestMapping("/pswupd")
    @ResponseBody
    public Map pswupd(Integer stuId,String password, Model model, HttpSession session){
        Map map=new HashMap();
        Student className = (Student)session.getAttribute("STU");
        String passwor=(String)session.getAttribute(className.getPassword());
        System.out.println("密码：----"+className.getPassword());
        boolean bln=xsdS.xgmm(stuId,password);
        System.out.println("新密码："+bln);
        if(bln){
            map.put("mag","反馈提交成功");
        }else{
            map.put("mag","反馈提交失败");
        }
        return map;
    }
//---------------------------------------------------------------------------------------


    /*
     *删除某个学生的请假信息
     * @param holidayId
     * @return map
     **/
    @RequestMapping("/deleteHolidayStudent")
    @ResponseBody
    public Map deleteHolidayId(Integer holidayId){
        Map map = new HashMap();
        boolean bln =  holidayStudentService.deleteHolidayStudent(holidayId);
        if (bln){
            map.put("msg","删除成功！");
        } else {
            map.put("msg","删除失败！");
        }
        return map;
    }

    /*
     *查看某个学生的请假条信息
     * @param holidayId、model
     * @return LookHolidayStudentContent
     **/
    @RequestMapping("/goLookHolidayStudentContent/{holidayId}")
    private String goLookWeeklyContent(Model model,@PathVariable Integer holidayId){
        List<Map> list = holidayStudentService.LookHolidayStudentContent(holidayId);
        model.addAttribute("LookHolidayStudentContent",list);
        System.out.println(list);
        return "LookHolidayStudentContent";
    }






    //*****************
    //学生考评
    @RequestMapping("/xstoupd/{jskhid}")
    public String xstoupd(@PathVariable("jskhid") String jskhid, Model model){
        Jskh ss=ks.xssel(jskhid);

        model.addAttribute("ss", JSON.toJSON(ss));//将对象转换成json对象


        return "xueshengkp";
    }

    //学生考评
    @RequestMapping("/xsupd")
    @ResponseBody
    public Map xsupd(Jskh jskh){
        Map map=new HashMap();
        boolean bln=ks.xsupd(jskh);
        if(bln){
            map.put("mag","考评成功");
        }else{
            map.put("mag","考评失败");
        }
        return map;
    }


    //学生考评
    @RequestMapping("/xstolist")
    public String xstolist(Model model){
        List<Studentclass>sclist=ks.sclist();
        model.addAttribute("sclist",sclist);
        return "xueshengkplist";
    }




    //学生考评
    @RequestMapping("/xslist")
    @ResponseBody
    public Map xslist(Integer page, Integer limit,Jskh jskh,HttpSession session){
        Student stu=(Student) session.getAttribute("STU");
        jskh.setClassid(stu.getClazz());
        System.out.println(stu.getClazz()+"hbjhbhj");
        List<Map> jskhlist=ks.jskhlist((page-1)*limit,limit,jskh);
        Map map=new HashMap();
        map.put("code",0);
        map.put("msg","成功");
        map.put("count",ks.jskhcount(jskh));//总页数
        map.put("data",jskhlist);//数据
        return map;
    }





}
